Operators
Identifiers and numeric constants can be combined, through the
use of operators, to form expressions. Each operator operates
on 32-bit values. If the value of a term occupies 8 or 16 bits,
it is sign extended to a 32-bit value.
The assembler provides both unary and binary operators. A unary
operator precedes its operand; a binary operator follows its first
operand, and precedes its second operand. For example:
!var | unary expression
var+5 | binary expression
The assembler recognizes the following unary operators:
Operator |
Desription |
- |
Unary minus : the result is the two's complement of the operand |
~ |
One's complement : the result is the one's complement of the operand |
! |
Logical negation : the result is 0 if the operand is non-zero, and 1 if the operand
is 0 |
The assembler recognizes the following binary operators:
Operator |
Description |
+ |
Addition : the result is the arithmetic addition of the two operands |
- |
Subtraction : the result is the arithmetic subtraction of the two operands |
* |
Multiplication : the result is the arithmetic multiplication of the two operands |
/ |
Division : the result is the arithmetic division of the two operands;
this is integer division, which truncates towards zero |
% |
Modulus : the result is the remainder that's produced when the first
operand is divided by the second (this operator applies only to
integral operands) |
>> |
Right shift : the result is the value of the first operand shifted to the
right, where the second operand specifies the number of bit positions
by which the first operand is to be shifted (this operator applies
only to integral operands). This is always an arithmetic shift
since all operators operate on signed operands. |
<< |
Left shift : the result is the value of the first operand shifted to the
left, where the second operand specifies the number of bit positions
by which the first operand is to be shifted (this operator applies
only to integral operands) |
& |
Bitwise AND : the result is the bitwise AND function of the two operands
(this operator applies only to integral operands) |
^ |
Bitwise exclusive OR : the result is the bitwise exclusive OR function of the two
operands (this operator applies only to integral operands) |
| |
Bitwise inclusive OR : the result is the bitwise inclusive OR function of the two
operands (this operator applies only to integral operands); this
operator can't be used on the M68000 microprocessor family, because
the `|' character is used there to mark the start of a comment |
< |
Less than : the result is 1 if the first operand is less than the second
operand, and 0 otherwise |
> |
Greater than : the result is 1 if the first operand is greater than the second
operand, and 0 otherwise |
<= |
Less than or equal : the result is 1 if the first operand is less than or equal
to the second operand, and 0 otherwise |
>= |
Greater than or equal : the result is 1 if the first operand is greater than or equal
to the second operand, and 0 otherwise |
== |
Equal : the result is 1 if the two operands are equal, and 0 otherwise |
!= |
Not equal (same as <> ): the result is 0 if the two operands are equal, and 1 otherwise |
Expressions
Expressions are combinations of terms joined together by binary
operators. An expression is always evaluated to a 32-bit value,
but in some situations a different value will be used:
- If the operand requires a one-byte value (a .byte directive, for example), the low-order eight bits of the expression
are used.
- If the operand requires a 16-bit value (a .short directive or a movem instruction, for example), the low-order 16 bits of the expression
are used.
All expressions are evaluated using the same operator precedence
rules that are used by the C programming language.
When an expression is evaluated its value is absolute, relocatable,
or external, as described below.
Absolute Expressions
An expression is absolute if its value is fixed. The following,
for example, are absolute:
- An expression whose terms are constants
- An identifier whose value is a constant via a direct assignment
statement
- A relocatable expression minus a relocatable term, if both items
belong to the same program section.
Relocatable Expressions
An expression (or term) is relocatable if its value is fixed relative
to a base address, but will have an offset value when it is linked
or loaded into memory. For example, all labels of a program defined
in relocatable sections are relocatable.
Expressions that contain relocatable terms must only add or subtract
constants to their value. For example, if the identifiers var and dat were defined in a relocatable section of the program, then the
following examples demonstrate the use of relocatable expressions:
Expression |
Description |
var |
is a simple relocatable term. Its value is an offset from the
base address of the current control section. |
var+5 |
is a simple relocatable expression. Since the value of var is an offset from the base address of the current control section,
adding a constant to it doesn't change its relocatable status. |
var*2 |
is not relocatable. Multiplying a relocatable term by a constant
invalidates the relocatable status of the expression. |
2-var |
is not relocatable. The expression can't be linked by adding var 's offset to it. |
var-dat+5 |
is a relocatable expression if both var and dat are both defined in some section--that is, if neither is undefined.
This form of relocatable expression is used for position-independent
code. |
External Expressions
An expression is external (or global ) if it contains an external identifier not defined in the current
program. In general, the same restrictions on expressions containing
relocatable identifiers apply to expressions containing external
identifiers. An exception is that the expression var-dat is incorrect when both var and dat are external identifiers (that is, you cannot subtract two external
relocatable expressions). Also, you cannot multiply or divide
any relocatable expression.